﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Collections.Specialized;

namespace Club.Helpers
{
    public static class GridPagerExtension
    {
        public static string GridPager(this HtmlHelper htmlHelper)
        {
            return GridPager(htmlHelper, new GridPagerProperties());
        }

        public static string GridPager(this HtmlHelper htmlHelper, GridPagerProperties properties)
        {
            return GenerateLinks(properties);
        }


        private static string GeneratePostBackUrl(int pageNumber, string key)
        {
            string url = HttpContext.Current.Request.Path;
            NameValueCollection page = new NameValueCollection();
            page.Add(key, pageNumber.ToString());

            string qString = QueryString.SetValues(page, HttpContext.Current.Request.RawUrl);

            if (qString.Length > 0)
                url += "?" + qString;
            return url;
        }

        private static string GenerateLinks(GridPagerProperties properties)
        {
            //StringBuilder pagerString = new StringBuilder();

            TagBuilder pagerDiv = new TagBuilder("div") { };
            pagerDiv.MergeAttributes(new Dictionary<string, string> { { "class", "pager" } });

            if (properties.PageCount > 1)
            {
                //create the previous tag
                if (properties.CurrentPageIndex > 0)
                {
                    string prevUrl = GeneratePostBackUrl(properties.CurrentPageIndex - 1, properties.PageKey);
                    TagBuilder prevTag = new TagBuilder("a")
                    {
                        InnerHtml = "<span>" + HttpUtility.HtmlEncode("<") + "</span>"
                    };
                    prevTag.MergeAttributes(new Dictionary<string, string> { { "href", prevUrl } });

                    pagerDiv.InnerHtml += prevTag.ToString(); ;
                    //pagerString.Append(prevTag.ToString());
                }

                for (int page = 0; page < properties.PageCount; page++)
                {
                    string url = GeneratePostBackUrl(page, properties.PageKey);
                    TagBuilder tag = new TagBuilder("a")
                    {
                        InnerHtml = "<span>" + HttpUtility.HtmlEncode((page + 1).ToString()) + "</span>"
                    };
                    tag.MergeAttributes(new Dictionary<string, string> { { "href", url } });


                    if (HttpContext.Current.Request.Url.PathAndQuery == url)
                        tag.Attributes.Add("class", "selected");
                    else if ((HttpContext.Current.Request.QueryString.Count == 0 || QueryString.GetInt(properties.PageKey) == 0) && page == 0)
                        tag.Attributes.Add("class", "selected");

                    TagBuilder label = new TagBuilder("label")
                    {
                        InnerHtml = HttpUtility.HtmlEncode("...")
                    };
                    label.MergeAttributes(new Dictionary<string, string> { { "text", "..." } });


                    if (properties.PageCount > 11)
                    {
                        if (properties.CurrentPageIndex < 7)
                        {
                            //beginning
                            if (page < 9 || ((properties.PageCount - page) < 3))
                                pagerDiv.InnerHtml += tag.ToString();
                            else if (page == 10)
                                pagerDiv.InnerHtml += label.ToString();
                        }
                        else if (properties.CurrentPageIndex >= (properties.PageCount - 7))
                        {
                            //end
                            if (page < 2 || (page >= properties.PageCount - 9))
                                pagerDiv.InnerHtml += tag.ToString();
                            else if (page == 2)
                                pagerDiv.InnerHtml += label.ToString();
                        }
                        else
                        {
                            //middle
                            if (page < 2)
                                pagerDiv.InnerHtml += tag.ToString();
                            else if (page == 2)
                                pagerDiv.InnerHtml += label.ToString();
                            else if ((page >= (properties.CurrentPageIndex - 4)) && (page <= (properties.CurrentPageIndex + 4)))
                                pagerDiv.InnerHtml += tag.ToString();
                            else if (page == properties.CurrentPageIndex + 5)
                                pagerDiv.InnerHtml += label.ToString();
                            else if (page >= properties.PageCount - 2)
                                pagerDiv.InnerHtml += tag.ToString();
                        }
                    }
                    else
                        pagerDiv.InnerHtml += tag.ToString();
                }

                //create the next tag
                if (properties.CurrentPageIndex < properties.PageCount - 1)
                {
                    string nextUrl = GeneratePostBackUrl(properties.CurrentPageIndex + 1, properties.PageKey);
                    TagBuilder nextTag = new TagBuilder("a")
                    {
                        InnerHtml = "<span>" + HttpUtility.HtmlEncode(">") + "</span>"
                    };
                    nextTag.MergeAttributes(new Dictionary<string, string> { { "href", nextUrl } });

                    pagerDiv.InnerHtml += nextTag.ToString();
                }
            }

            // create the total items tag
            TagBuilder countDiv = new TagBuilder("div")
            {
                InnerHtml = String.Format("{0} items", properties.RecordCount)
            };
            countDiv.MergeAttributes(new Dictionary<string, string> { { "class", "totalrecords" } });

            pagerDiv.InnerHtml += countDiv.ToString();

            TagBuilder clearDiv = new TagBuilder("div") { };
            clearDiv.MergeAttributes(new Dictionary<string, string> { { "class", "clear" } });

            pagerDiv.InnerHtml += clearDiv.ToString();

            return pagerDiv.ToString();
        }
    }

    public class GridPagerProperties
    {
        public string PageKey { get; set; }
        public int PageSize { get; set; }
        public int RecordCount { get; set; }
        public int PageCount
        {
            get
            {
                if (PageSize > 0)
                    return (RecordCount / PageSize) + ((RecordCount % PageSize == 0) ? 0 : 1);
                else
                    return 0;
            }
        }

        public int CurrentPageIndex
        {
            get
            {
                if (QueryString.GetInt(PageKey) > 0)
                    return QueryString.GetInt(PageKey);
                else
                    return 0;
            }
        }
    }
}
